/*
 * ShotMemoryStore.cpp
 *
 *  Created on: Oct 6, 2012
 *      Author: Administrator
 */

#include <FIo.h>
#include <FSystem.h>
#include "ShotMemoryStore.h"

using namespace Osp::Base;
using namespace Osp::Io;


ShotMemoryStore::ShotMemoryStore() {
	counter = 0;
	rootDirName = new String(L"/Home/Shots/");
	rootDir = new Directory();
	result r = rootDir -> Construct(rootDirName->GetPointer());
	AppLog("Store %S constructed:%s\n", rootDirName->GetPointer(), GetErrorMessage(r));
}

ShotMemoryStore::~ShotMemoryStore() {
	// TODO Auto-generated distructor stub
}

Shot*
ShotMemoryStore::GetLastShotN(void) {

	ReportMemoryState();

	result r = E_SUCCESS;

	bool hasFiles = false;
	String* rootName = new String(*rootDirName);
	DirEnumerator* pDirEnum = rootDir -> ReadN();
	int counter = 0;
	while(pDirEnum->MoveNext() == E_SUCCESS) {
		pDirEnum->GetCurrentDirEntry();
		DirEntry dirEntry = pDirEnum->GetCurrentDirEntry();
		AppLogDebug("File name is %S", dirEntry.GetName().GetPointer());
		if (!dirEntry.IsDirectory()) {
			if (!hasFiles) {
				rootName->Append(dirEntry.GetName());
				hasFiles = true;
			}
			counter++;
		}
	}
	delete pDirEnum;
	AppLog("%d shots stored", counter);

	if (!hasFiles) {
		return null;
	}

	File* file = new File();
	r = file->Construct(*rootName, "r");
	AppLogDebug("File %S construct result is %S", rootName->GetPointer(), GetErrorMessage(r));
	FileAttributes* attr = new FileAttributes();
	r = File::GetAttributes(*rootName, *attr);
	AppLogDebug("File attributes result is %S", GetErrorMessage(r));

	ByteBuffer* buffer = new ByteBuffer();
	r = buffer->Construct(attr->GetFileSize());
	AppLogDebug("Buffer result is %S", GetErrorMessage(r));

	file->Read(*buffer);
	file->~File();
	r = File::Remove(*rootName);

	AppLog("File %S deleted %S", rootName->GetPointer(), GetErrorMessage(r));

	buffer->Flip();

	AppLogDebug("Buffer position %d", buffer->GetPosition());
	AppLogDebug("Buffer limit %d", buffer->GetLimit());

	AppLog("File size is %d", (int)(attr->GetFileSize()));

	Shot* shot = new Shot(buffer, rootName, buffer->GetLimit());

	return shot;

}

void
ShotMemoryStore::StoreShotN(Osp::Base::ByteBuffer& data) {
	File* file = new File();
	String* fileName = new String(rootDirName->GetPointer());
	fileName->Append(counter++);
	file->Construct(*fileName, L"w+");
	file->Write(data);
	file->Flush();
	if (GetLastResult()==E_SUCCESS) {
		AppLog("File %S is stored", fileName->GetPointer());
	} else {
		AppLog("File %S failed to store %S", fileName->GetPointer(), GetErrorMessage(GetLastResult()));
	}
	file->~File();
	delete file;
	fileName->~String();
	delete fileName;
	ReportMemoryState();
}

void
ShotMemoryStore::ReportMemoryState(void) {

	result r = E_SUCCESS;

	int avaMemeory;

	String aMemory(L"AllocatedMemory");

	r = Osp::System::RuntimeInfo::GetValue(aMemory, avaMemeory);

	if(IsFailed(r)) {
		AppLog("Failed to get AvailableMemory");
	} else {
		AppLog("Allocated Memory: %d", avaMemeory);
	}

}

void
ShotMemoryStore::Clean(void) {
	DirEnumerator* pDirEnum = rootDir -> ReadN();
	while(pDirEnum->MoveNext() == E_SUCCESS) {
		pDirEnum->GetCurrentDirEntry();
		DirEntry dirEntry = pDirEnum->GetCurrentDirEntry();
		if (!dirEntry.IsDirectory()) {
			String* fileName = new String(*rootDirName);
			fileName -> Append(dirEntry.GetName());
			File::Remove(*fileName);
			delete fileName;
		}
	}
	delete pDirEnum;
}
